package Thread.letter;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 下面我们先简单地实现线程间的通信，使用sleep结合while死循环操作共享变量的方式来进行。
 * 上面的程序运行时好像并没有什么问题，虽然实现了线程间的通信，但是线程2是用死循环不停地轮询
 * 来实现的，这样会浪费CPU资源，并且存在以下的问题。
 * 如果轮训时间很小，则更浪费CPU资源。
 * 如果轮询时间很大，则可能得不到想要的数据。
 * 如果去掉间隔时间，线程2也可能得不到想要的数据。
 * 可以发现，这种实现方式存在很大的弊端的，并且很容易出现可见性问题（这个我们后面讨论），因此
 * 我们需要引入一种机制——等待/通知机制
 */
public class Test1 {

    @Test
    void test() {
        List<String> list = new ArrayList<>();
        new Thread(new Test1Thread1(list)).start();
        new Thread(new Test1Thread2(list)).start();
    }
}

class Test1Thread1 implements Runnable {
    private List<String> list;

    public Test1Thread1(List<String> list) {
        this.list = list;
    }

    @Override
    public void run() {
        try {
            for (int i = 0; i < 10; i++) {
                list.add("aaa");
                System.out.println("添加了" + (i + 1) + "个元素");
                TimeUnit.SECONDS.sleep(1);
            }
        } catch (Exception e) {
        }
    }
}

class Test1Thread2 implements Runnable {
    private List<String> list;

    public Test1Thread2(List<String> list) {
        this.list = list;
    }

    public void run() {
        try {
            while (true) {
                TimeUnit.SECONDS.sleep(3);
                System.out.println(list.size());
                if (list.size() == 5) {
                    System.out.println("集合大小超过5，线程退出");
                    break;
                }
            }
        } catch (Exception e) {
        }
    }
}